//
// Created by wxd on 2025/8/3.
//

#include "FrameCounter.h"

void FrameCounter::updateFrame() {
    std::lock_guard<std::mutex> lock(m_FpsMutex);

    auto now = Clock::now();

    // 初始化检查
    if (m_LastFrameTimeStartPoint.time_since_epoch().count() == 0) {
        m_LastFrameTimeStartPoint = now;
        m_LastFrameTimePoint = now;
        return;  // 跳过第一帧
    }

    if (m_LastFrameTimePoint != TimePoint{} &&
       std::chrono::duration_cast<std::chrono::milliseconds>(now - m_LastFrameTimePoint).count() < 16) {
       return; // 跳过高频调用
    }

    // 更新当前帧时间，计数，帧间隔, 第一帧状态
    m_CurrentFrameTimePoint = now;
    m_FrameCount++;
    if (m_LastFrameTimePoint != TimePoint{}) {
        m_CurrentDeltaFrameTime = m_CurrentFrameTimePoint - m_LastFrameTimePoint;
        m_IntervalFrameHistory.push_back(m_CurrentDeltaFrameTime.count());
    }
    m_LastFrameTimePoint = m_CurrentFrameTimePoint;
    m_IsFirstFrame = false;

    // 获取当前帧时间间隔的大小，单位秒
    double deltaFrameSec = std::chrono::duration_cast<std::chrono::duration<double>>(
        now - m_LastFrameTimeStartPoint).count();


    // 避免delta过小导致溢出问题
    if (deltaFrameSec < 1e-6) deltaFrameSec = 1e-6;

    if (deltaFrameSec >= 1.f) {
        // 计算实际帧和平滑帧
        m_CurrentRealFPS = m_FrameCount / deltaFrameSec;
        m_CurrentSmoothFPS = m_EMA_Alpha * m_CurrentRealFPS + (1.f - m_EMA_Alpha) * m_CurrentSmoothFPS;

        // 更新当前峰值
        m_MinRealFPS = std::min(m_MinRealFPS, m_CurrentRealFPS);
        m_MaxRealFPS = std::max(m_MaxRealFPS, m_CurrentRealFPS);
        m_MinSmoothFPS = std::min(m_MinSmoothFPS, m_CurrentSmoothFPS);
        m_MaxSmoothFPS = std::max(m_MaxSmoothFPS, m_CurrentSmoothFPS);

        // 判断当前缓存是否超过帧窗口的大小，如果超过，移除第一个帧记录
        if (m_RealFpsHistory.size() >= m_HistoryMaxSize) {
            m_RealFpsHistory.erase(m_RealFpsHistory.begin());
        }
        if (m_SmoothFpsHistory.size() >= m_HistoryMaxSize) {
            m_SmoothFpsHistory.erase(m_SmoothFpsHistory.begin());
        }

        // 缓存记录
        m_RealFpsHistory.push_back(m_CurrentRealFPS);
        m_SmoothFpsHistory.push_back(m_CurrentSmoothFPS);

        // DEBUG模式输出当前FPS日志
#ifdef LOG_DEBUG
        std::cout << "frame count: " << m_FrameCount << "; deltaFrameSec: " << deltaFrameSec << "; realFPS: " << m_CurrentRealFPS
        << "; smoothFPS: " << m_CurrentSmoothFPS << "\n";
#endif

        // 重置, 重新统计1s内的帧数
        m_FrameCount = 0;
        m_LastFrameTimeStartPoint = Clock::now();
    }
}

double FrameCounter::getRealFPS() const {
    std::lock_guard<std::mutex> lock(m_FpsMutex);
    double realFPS = 0;
    if (m_FrameCount > 0) {
        const Duration elapsed = Clock::now() - m_LastFrameTimeStartPoint;
        realFPS = m_FrameCount / elapsed.count();
    }
    return realFPS;
}

double FrameCounter::getSmoothFPS() const {
    std::lock_guard<std::mutex> lock(m_FpsMutex);
    double currentSmoothFPS = 0;
    if (m_FrameCount > 0) {
        const Duration elapsed = Clock::now() - m_LastFrameTimeStartPoint;
        const double curFPS = m_FrameCount / elapsed.count();
        currentSmoothFPS = m_EMA_Alpha * m_CurrentSmoothFPS + (1.f - m_EMA_Alpha) * curFPS;
    }
    return currentSmoothFPS;
}


double FrameCounter::getRealMinFPS() const {
    std::lock_guard<std::mutex> lock(m_FpsMutex);
    return m_MinRealFPS;
}

double FrameCounter::getRealMaxFPS() const {
    std::lock_guard<std::mutex> lock(m_FpsMutex);
    return m_MaxRealFPS;
}

double FrameCounter::getSmoothMinFPS() const {
    std::lock_guard<std::mutex> lock(m_FpsMutex);
    return m_MinSmoothFPS;
}

double FrameCounter::getSmoothMaxFPS() const {
    std::lock_guard<std::mutex> lock(m_FpsMutex);
    return m_MaxSmoothFPS;
}

double FrameCounter::getRealAverageFPS(bool isWeighted) const {
    if (m_RealFpsHistory.empty()) return 0;

    double avgFps = 0;

    if (isWeighted && !m_AlphaCoef.empty()) {
        // 加权平均
        const size_t size = std::min(m_RealFpsHistory.size(), m_AlphaCoef.size());

        for (int i = 0; i < size; i++) {
            avgFps += m_RealFpsHistory[i] * m_AlphaCoef[i];
        }
    } else {
        // 非加权平均
        for (const auto fps : m_RealFpsHistory) {
            avgFps += fps;
        }
        avgFps /= m_RealFpsHistory.size();
    }

    return avgFps;
}

